﻿using System.Reflection;
using System.Xml;

namespace HuaXingSDK
{
    public abstract class HXFrom<T> : HXFrom where T : HXReply
    {
        protected HXFrom(string outerXml) : base(outerXml)
        {
        }

        public abstract T ToReply();
    }

    public abstract class HXFrom : XmlToEntity
    {
        public string ChannelCode { get; internal set; }
        public string ChannelFlow { get; internal set; }
        public int ChannelDate { get; internal set; }
        public int ChannelTime { get; internal set; }
        public string TransCode { get; internal set; }

        protected const string ROOT = "Document";
        protected const string HEADER = "header";
        protected const string BODY = "body";
        protected const string XMLPARA = "XMLPARA";

        protected HXFrom(string outerXml) : base(outerXml)
        {

        }

        protected override void SetValue(XmlNode node)
        {
            if (node.Name.OICEquals(HEADER))
            {
                foreach (XmlNode sub in node)
                {
                    SetValue(sub);
                }
            }
            else if (node.Name.OICEquals(BODY))
            {
                foreach (XmlNode sub in node)
                {
                    if (sub.Name.OICEquals(XMLPARA))
                    {
                        var paraXml = new XmlDocument();
                        try
                        {
                            paraXml.LoadXml(Uilts.DecryptXmlPara(sub.OuterXml));
                        }
                        catch
                        {
                            paraXml.LoadXml(sub.OuterXml);
                        }
                        if (paraXml.DocumentElement != null)
                        {
                            foreach (XmlNode sub2 in paraXml.DocumentElement)
                            {
                                SetValue(sub2);
                            }
                        }
                    }
                    else
                    {
                        SetValue(sub);
                    }
                }
            }
            else
            {
                var p = GetType().GetProperty(node.Name,
                            BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);
                if (p != null)
                {
                    var value = GetValue(p.PropertyType, node);
                    if (value != null)
                    {
                        if (p.Name.OICEquals(nameof(TransCode)) && !string.IsNullOrEmpty(TransCode) &&
                            !TransCode.OICEquals(value.ToString()))
                            throw new HXException($"两个{nameof(TransCode)}的值不一致：{TransCode}，{value}");
                        p.SetValue(this, value, null);
                    }
                }
            }
        }
    }
}
